    <!DOCTYPE html>
<html lang="zh-cn">
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<meta name="author" content="nodejh">
		<meta name="description" content="My Blog">
		<meta name="generator" content="Hugo 0.31.1" />
		<title>JS 判断字符串是否是拼音音节 &middot; nodejh</title>
		<link rel="shortcut icon" href="http://nodejh.com/images/favicon.ico">
		<link rel="stylesheet" href="http://nodejh.com/css/style.css">
		<link rel="stylesheet" href="http://nodejh.com/css/highlight.css">
		

		
		<link rel="stylesheet" href="http://nodejh.com/css/font-awesome.min.css">
		

		
		<link href="http://nodejh.com/index.xml" rel="alternate" type="application/rss+xml" title="nodejh" />
		
	</head>

    <body>
       <nav class="main-nav">
	
	
		<a href='http://nodejh.com/'> <span class="arrow">←</span>Home</a>
	
	<a href='http://nodejh.com/post'>Archive</a>
	<a href='http://nodejh.com/tags'>Tags</a>
	<a href='http://nodejh.com/projects'>Projects</a>
	<a href='http://nodejh.com/about'>About</a>

	

	
	<a class="cta" href="http://nodejh.com/index.xml">Subscribe</a>
	
</nav>


        <section id="wrapper" class="post">
            <article>
                <header>
                    <h1>
                        JS 判断字符串是否是拼音音节
                    </h1>
                    <h2 class="headline">
                    Apr 13, 2016 10:35
                    · 1224 words
                    · 3 minutes read
                      <span class="tags">
                      
                      
                          
                              <a href="http://nodejh.com/tags/javascript">JavaScript</a>
                          
                      
                      
                      </span>
                    </h2>
                </header>
                
                  
                    <div id="toc">
                      <nav id="TableOfContents">
<ul>
<li>
<ul>
<li><a href="#最终函数">最终函数</a></li>
<li><a href="#思路">思路</a>
<ul>
<li>
<ul>
<li><a href="#1-找到所有拼音音节表">1. 找到所有拼音音节表</a></li>
<li><a href="#2-递归判断字符串">2. 递归判断字符串</a></li>
<li><a href="#3-还是递归">3. 还是递归</a></li>
</ul></li>
</ul></li>
</ul></li>
</ul>
</nav>
                    </div>
                  
                
                <section id="post-body">
                    <h2 id="最终函数">最终函数</h2>

<p>最近在抓取 Rice 大学的博士生姓名，并从中获取到中国人的姓名。由于博士有中国人和外国人，而中国人的姓名是由拼音组成，所以最终需求是这样的，判断一个字符串是否是由拼音音节组成。于是写了下面这个函数：</p>

<p></p>

<pre><code>/**
 * 判断输入的一个字符串是不是拼音
 * @param string 需要测试的字符串
 * @returns {*}
 */
function is_pinyin(string) {

  var list = ['a', 'ai', 'an', 'ang', 'ao', 'ba', 'bai', 'ban', 'bang', 'bao', 'bei', 'ben',
    'beng', 'bi', 'bian', 'biao', 'bie', 'bin', 'bing', 'bo', 'bu', 'ca', 'cai', 'can', 'cang',
    'cao', 'ce', 'cen', 'ceng', 'cha', 'chai', 'chan', 'chang', 'chao', 'che', 'chen', 'cheng', 'chi',
    'chong', 'chou', 'chu', 'chua', 'chuai', 'chuan', 'chuang', 'chui', 'chun', 'chuo', 'ci', 'cong',
    'cou', 'cu', 'cuan', 'cui', 'cun', 'cuo', 'da', 'dai', 'dan', 'dang', 'dao', 'de', 'dei', 'den',
    'deng', 'di', 'dia', 'dian', 'diao', 'die', 'ding', 'diu', 'dong', 'dou', 'du', 'duan', 'dui', 'dun',
    'duo', 'e', 'en', 'eng', 'er', 'fa', 'fan', 'fang', 'fei', 'fen', 'feng', 'fiao', 'fo', 'fou', 'fu',
    'ga', 'gai', 'gan', 'gang', 'gao', 'ge', 'gei', 'gen', 'geng', 'gong', 'gou', 'gu', 'gua', 'guai', 'guan',
    'guang', 'gui', 'gun', 'guo', 'ha', 'hai', 'han', 'hang', 'hao', 'he', 'hei', 'hen', 'heng', 'hong', 'hou',
    'hu', 'hua', 'huai', 'huan', 'huang', 'hui', 'hun', 'huo', 'ji', 'jia', 'jian', 'jiang', 'jiao', 'jie',
    'jin', 'jing', 'jiong', 'jiu', 'ju', 'juan', 'jue', 'ka', 'kai', 'kan', 'kang', 'kao', 'ke', 'ken',
    'keng', 'kong', 'kou', 'ku', 'kua', 'kuai', 'kuan', 'kuang', 'kui', 'kun', 'kuo', 'la', 'lai', 'lan',
    'lang', 'lao', 'le', 'lei', 'leng', 'li', 'lia', 'lian', 'liang', 'liao', 'lie', 'lin', 'ling', 'liu',
    'lo', 'long', 'lou', 'lu', 'luan', 'lun', 'luo', 'lv', 'lve', 'ma', 'mai', 'man', 'mang', 'mao', 'me',
    'mei', 'men', 'meng', 'mi', 'mian', 'miao', 'mie', 'min', 'ming', 'miu', 'mo', 'mou', 'mu', 'na', 'nai',
    'nan', 'nang', 'nao', 'ne', 'nei', 'nen', 'neng', 'ni', 'nian', 'niang', 'niao', 'nie', 'nin', 'ning',
    'niu', 'nong', 'nou', 'nu', 'nuan', 'nun', 'nuo', 'nv', 'nve', 'o', 'ou', 'pa', 'pai', 'pan', 'pang', 'pao',
    'pei', 'pen', 'peng', 'pi', 'pian', 'piao', 'pie', 'pin', 'ping', 'po', 'pou', 'pu', 'qi', 'qia', 'qian',
    'qiang', 'qiao', 'qie', 'qin', 'qing', 'qiong', 'qiu', 'qu', 'quan', 'que', 'qun', 'ran', 'rang', 'rao',
    're', 'ren', 'reng', 'ri', 'rong', 'rou', 'ru', 'rua', 'ruan', 'rui', 'run', 'ruo', 'sa', 'sai', 'san',
    'sang', 'sao', 'se', 'sen', 'seng', 'sha', 'shai', 'shan', 'shang', 'shao', 'she', 'shei', 'shen', 'sheng',
    'shi', 'shou', 'shu', 'shua', 'shuai', 'shuan', 'shuang', 'shui', 'shun', 'shuo', 'si', 'song', 'sou',
    'su', 'suan', 'sui', 'sun', 'suo', 'ta', 'tai', 'tan', 'tang', 'tao', 'te', 'tei', 'teng', 'ti', 'tian',
    'tiao', 'tie', 'ting', 'tong', 'tou', 'tu', 'tuan', 'tui', 'tun', 'tuo', 'wa', 'wai', 'wan', 'wang',
    'wei', 'wen', 'weng', 'wo', 'wu', 'xi', 'xia', 'xian', 'xiang', 'xiao', 'xie', 'xin', 'xing', 'xiong',
    'xiu', 'xu', 'xuan', 'xue', 'xun', 'ya', 'yan', 'yang', 'yao', 'ye', 'yi', 'yin', 'ying', 'yo', 'yong',
    'you', 'yu', 'yuan', 'yue', 'yun', 'za', 'zai', 'zan', 'zang', 'zao', 'ze', 'zei', 'zen', 'zeng', 'zha',
    'zhai', 'zhan', 'zhang', 'zhao', 'zhe', 'zhei', 'zhen', 'zheng', 'zhi', 'zhong', 'zhou', 'zhu', 'zhua',
    'zhuai', 'zhuan', 'zhuang', 'zhui', 'zhun', 'zhuo', 'zi', 'zong', 'zou', 'zu', 'zuan', 'zui', 'zun', 'zuo'];
  var lowerString = string.toLowerCase();
  var length = lowerString.length;
  var index = -1;

  for (var i=0; i&lt;length; i++) {
    var name = lowerString.substring(0, i+1);
    index = list.lastIndexOf(name) &gt; index ? list.lastIndexOf(name) : index;
  }

  // 判断当前 lowerString 是不是拼音(lowerString 在 list 中就是;不在就不是)
  if (index &gt;= 0) {
    var item = list[index];
     lowerString = lowerString.substring(item.length);
    if (lowerString.length == 0) {
      return string;
    } else {
       return arguments.callee(lowerString);
    }
  } else {
    return false;
  }
}
</code></pre>

<h2 id="思路">思路</h2>

<h4 id="1-找到所有拼音音节表">1. 找到所有拼音音节表</h4>

<p>首先是找到所有的拼音列表，将其存入数组 <code>ist</code>。</p>

<p>汉语的拼音音节共 399 个，可以在百度百科找到：<a href="http://baike.baidu.com/view/1253220.htm">汉语拼音音节</a></p>

<h4 id="2-递归判断字符串">2. 递归判断字符串</h4>

<p>接下来要循环判断传入的字符串是否是拼音音节。也就是说，我们要判断所传入的字符串是否在 <code>lsit</code> 数组中，聪明的可能想到了，可以用 <code>indexOf()</code> 来判断。</p>

<p>那么问题来了，我们所要判断的字符串是姓名，形如 <code>jianghang</code>，是由两个甚至更多的拼音音节组成的。所以不能直接 <code>list.indexOf('jianghang')</code>，而是要不断循环截取 <code>jianghang</code> 这个字符串，判读所截取的字符串是否在 <code>list</code> 数组中。如第一次循环截取的是 <code>j</code>，然后判断 <code>j</code> 是否在 <code>lsit</code> 里面，如果不在，则继续截取 <code>ji</code> 再判断；如果是，则又从字符串的第三位开始继续判断，直到判断完整个字符串。其实也就是递归。</p>

<p>然后可能你又发现了，这么做还是有问题。因为 <code>ji</code> 是拼音音节，<code>jia</code>、<code>jian</code>、<code>jiang</code> 也都是拼音音节。所以这就涉及到一个最优的问题，我们要找到 <code>jiang</code> 而不是 <code>ji</code> 或其它。</p>

<p>根据 <code>lsit</code> 的规则，排在后面的音节总是最优的音节。所以我们使用 <code>lastIndexOf()</code> 对数组从后往前筛选。</p>

<h4 id="3-还是递归">3. 还是递归</h4>

<p>这里需要注意的是 <code>return arguments.callee(lowerString);</code> 这一行。<code>arguments</code> 是一个类数组对象，它包含着传入函数的所有参数。这个对象有一个 <code>callee</code> 属性，该属性是一个指针，指向拥有 <code>arguments</code> 对象的函数。</p>

<p>这里我们使用 <code>return  arguments.callee(lowerString)</code> 而不是用 <code>return is_pinyin(lowerString)</code> 的好处就是，当我们改变函数名的时候，我们仍然可以正确使用该函数。</p>

<hr />

<p>Github Issue: <a href="https://github.com/nodejh/nodejh.github.io/issues/8">https://github.com/nodejh/nodejh.github.io/issues/8</a></p>
                </section>
            </article>

            

            
                <div id="disqus_thread"></div>
<script type="text/javascript">
    var disqus_shortname = 'nodejh'; 

     
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>

            

            
                <ul id="post-list" class="archive readmore">
    <h3>Read more</h3>
    
    
        
        <li>
            <a href="http://nodejh.com/post/how-to-vertically-middle-align-floated-elements-with-flexbox/">使用 Flexbox 使浮动元素垂直居中<aside class="dates">Jul 28</aside></a>
        </li>
        
   
    
        
        <li>
            <a href="http://nodejh.com/post/css-responsive-navigation-menu/">纯 CSS 实现响应式导航菜单<aside class="dates">Jul 28</aside></a>
        </li>
        
   
    
        
        <li>
            <a href="http://nodejh.com/post/vue2-tutorials-02-todolist/">实现一个TodoList - Vue2 Tutorials (二)<aside class="dates">Jul 17</aside></a>
        </li>
        
   
    
        
        <li>
            <a href="http://nodejh.com/post/electron-quick-start/">Electron 快速入门<aside class="dates">Jul 6</aside></a>
        </li>
        
   
    
        
        <li>
            <a href="http://nodejh.com/post/vue2-tutorials-01-quick-start/">快速入门 - Vue2 Tutorials (一)<aside class="dates">Jul 6</aside></a>
        </li>
        
   
    
        
        <li>
            <a href="http://nodejh.com/post/project-documentation-with-hexo-static-site-generator/">使用 Hexo 创建项目文档网站<aside class="dates">Jul 5</aside></a>
        </li>
        
   
    
        
        <li>
            <a href="http://nodejh.com/post/handy-mysql-commands/">常用 MySQL 命令<aside class="dates">Mar 30</aside></a>
        </li>
        
   
    
        
        <li>
            <a href="http://nodejh.com/post/understand-the-oracle-startup-process/">深入理解 Oracle 启动原理<aside class="dates">Mar 26</aside></a>
        </li>
        
   
    
        
        <li>
            <a href="http://nodejh.com/post/setting-environmental-variables-in-macos/">macOS/Linux 环境变量设置<aside class="dates">Mar 19</aside></a>
        </li>
        
   
    
        
        <li>
            <a href="http://nodejh.com/post/how-to-create-auto-increment-column-in-oracle/">在 Oracle 中设置自增列<aside class="dates">Feb 20</aside></a>
        </li>
        
   
</ul>
            

            <footer id="footer">
    
        <div id="social">

	
	
    <a class="symbol" href="https://www.facebook.com/nodejh">
        <i class="fa fa-facebook-square"></i>
    </a>
    
    <a class="symbol" href="https://www.github.com/nodejh">
        <i class="fa fa-github-square"></i>
    </a>
    
    <a class="symbol" href="https://www.twitter.com/nodejh">
        <i class="fa fa-twitter-square"></i>
    </a>
    


</div>

    
    <p class="small">
    
       © Copyright 2017 <i class="fa fa-heart" aria-hidden="true"></i> nodejh
    
    </p>
    <p class="small">
        Powered by <a href="http://www.gohugo.io/">Hugo</a> Theme By <a href="https://github.com/nodejh/hugo-theme-cactus-plus">nodejh</a>
    </p>
</footer>

        </section>

        <script src="http://nodejh.com/js/jquery-2.2.4.min.js"></script>
<script src="http://nodejh.com/js/main.js"></script>
<script src="http://nodejh.com/js/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>




  
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

ga('create', 'UA-84989670-1', 'auto');
ga('send', 'pageview');
</script>




<script>
var baiduAnalytics = '39843ea392201290bd6f76173d2e1633';
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?" + baiduAnalytics;
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(hm, s);
})();
</script>


    </body>
</html>
